package com.fc.test.util.wx;

import com.fc.test.util.GetNewDate;
import com.fc.test.util.wx.Utils.MD5Util;
import com.fc.test.util.wx.Utils.OrderUtil;
import com.fc.test.util.wx.Utils.XMLUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;


import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;

/**
 * 生成预支付订单号
 * 
 * @author Sunlight
 *
 */
public class WxXcxPayService {
	public static final String appid = "wxd2eb33a60062405f";
	public static final String mch_id = "1552157601";
	public static final String sign_type = "MD5";
	public static final String notify_url = "https://sqabw.com/apiOrderController/getWxPayResult";
	//public static final String notify_url = "http://sunwenli.free.idcfengye.com/getWxPayResult.client";
	public static final String key = "81285e88d557e9b29a587eaf4bdc5666";
	public static final String trade_type = "JSAPI";
	public static final String appSecret = "3cce6fec502ad76416901fe57b774330";


//	public static final String appid = "wx947b084ecab2368b";
//	public static final String mch_id = "1528859631";
//	public static final String key = "UvdIgX24Z5CRDKJl8JsFwMt9GFh78jtL";
//	public static final String appSecret = "73c737629bd7945dc01ea3a709abbd8c";
	/**
	 * 获取code
	 */
	public static String code_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx1dc52369c9f09074&redirect_uri=http://xiaohongmaoshare.com&response_type=code&scope=snsapi_base&state=STATE";
	/**
	 * 获取openId
	 */
	public static String open_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
	
	/**
	* 统一下单地址
	*/
	public static final String prepayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	/**
	* @描述	扫码支付预下单方法
	* @作者	易涛
	* @时间	2018年12月4日 下午3:47:40
	* @param openId
	* @param ip
	* @param body
	* @param detail
	* @return	参数
	*/
	public static Map<String, Object> createXcxPrepay(String openId, String ip, String orderFromNumber, String money, String body, String detail) {
		// 创建HttpClientBuilder
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		// HttpClient
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		HttpPost httpPost = new HttpPost(prepayUrl);
		try {
			String nonce_str = OrderUtil.CreateNoncestr();
			httpPost.setEntity(new StringEntity(getXcxPackage(openId, ip, nonce_str, orderFromNumber, money, body, detail), "utf-8"));
			HttpResponse httpResponse = closeableHttpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			if (httpEntity != null) {
				// 打印响应内容
				String result = EntityUtils.toString(httpEntity, "UTF-8");
				result = result.replaceAll("<![CDATA[|]]>", "");
				System.out.println(result);
				Map<String, Object> map = XMLUtil.doXMLParse(result);
				return signAgain(nonce_str, map.get("prepay_id").toString());
			}
			// 释放资源
			closeableHttpClient.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	* @描述	扫码支付转码
	* @作者	易涛
	* @时间	2018年12月4日 下午3:47:59
	* @param openid
	* @param ip
	* @param nonce_str
	* @param body
	* @param detail
	* @return	参数
	*/
	private static String getXcxPackage(String openid, String ip, String nonce_str, String orderFromNumber, String money, String body, String detail) throws UnsupportedEncodingException {
		SortedMap<String, String> infoMap = new TreeMap<String, String>();
		infoMap.put("appid", appid);
		infoMap.put("body", body);
		infoMap.put("detail", detail);
		infoMap.put("device_info", "WEB");
		infoMap.put("mch_id", mch_id);
		infoMap.put("nonce_str", nonce_str);
		infoMap.put("notify_url", notify_url);
//		String ope=" openid";
//		String o=new String(ope.getBytes("GBK") , "GBK");
//		infoMap.put("openid", o);
		infoMap.put("openid", openid);
		infoMap.put("out_trade_no", String.valueOf(orderFromNumber));
		infoMap.put("sign_type", sign_type);
		infoMap.put("spbill_create_ip", ip);
		Long times = System.currentTimeMillis();
		infoMap.put("time_expire", String.valueOf(GetNewDate.getTime(times + 5 * 60 * 1000, "yyyyMMddHHmmss")));
		infoMap.put("time_start", String.valueOf(GetNewDate.getTime(times, "yyyyMMddHHmmss")));
		infoMap.put("total_fee", String.format("%.0f", Float.parseFloat(String.valueOf(money)) * 100));
		infoMap.put("trade_type", trade_type);
		System.out.println(infoMap);
		StringBuilder sb = new StringBuilder();
		for (String key : infoMap.keySet()) {
			sb.append(key).append("=").append(infoMap.get(key)).append("&");
		}
		sb.append("key=" + key);
		System.out.println(sb.toString());
		infoMap.put("sign", MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase());
		String xml = createXML(infoMap);
		String x=new String(xml.getBytes("GBK") , "GBK");
		System.out.println(xml);
		return x.toString();
	}

	/**
	* @描述	二次签名
	* @作者	易涛
	* @时间	2018年12月4日 下午3:48:56
	* @param nonce_str
	* @param prepay_id
	* @return	参数
	*/
	private static Map<String, Object> signAgain(String nonce_str, String prepay_id) {
		String timestamp = (System.currentTimeMillis() + "").substring(0, 10);
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		finalpackage.put("appId", appid);
		finalpackage.put("nonceStr", nonce_str);
		finalpackage.put("package", "prepay_id="+prepay_id);
		finalpackage.put("signType", sign_type);
		finalpackage.put("timeStamp", timestamp);

		StringBuilder sb = new StringBuilder();
		for (String key : finalpackage.keySet()) {
			sb.append(key).append("=").append(finalpackage.get(key)).append("&");
		}
		sb.append("key=" + key);
		String sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
		Map<String, Object> map = new HashMap<>();
		map.put("noncestr", nonce_str);
		map.put("timestamp", timestamp);
		map.put("signType", "MD5");
		map.put("appid", WxXcxPayService.appid);
		map.put("paypackage", "prepay_id="+prepay_id);
		map.put("paySign", sign);
		try {
			map.put("signature", GetJSSDKParameter.getWechatJsParameter(map).get("signature"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	* @描述	map转成特定的xml
	* @作者	易涛
	* @时间	2018年12月4日 下午3:50:01
	* @param infoMap
	* @return	参数
	*/
	private static String createXML(SortedMap<String, String> infoMap) {
		StringBuilder xml = new StringBuilder();
		xml.append("<xml>\n");
		Set<Entry<String,String>> entry1=infoMap.entrySet();
		Iterator<Entry<String,String>> it=entry1.iterator();
		while(it.hasNext()) {
			Entry<String,String> entry=it.next();
			if ("detail".equals(entry.getKey())) {
				xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
			} else {
				xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
			}
		}
		xml.append("</xml>");
		System.out.println(xml.toString());
		return xml.toString();
	}

	/**
	 * 根据code获取openId
	 * @param requestUrl
	 * @param requestMethod
	 * @return
	 */
	public static String httpsRequest(String requestUrl, String requestMethod){
		try{
			URL url = new URL(requestUrl);
			HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestMethod(requestMethod);
			// 从输入流读取返回内容
			InputStream inputStream = connection.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			connection.disconnect();
			return buffer.toString();
		}catch(Exception e){
			return null;
		}
	}

	/**
	* @描述	获取用户的openId，并放入session
	* @作者	易涛
	* @时间	2018年12月4日 下午3:50:27
	* @param code
	* @return	参数
	*/
	public static String getOpenId(String code) {
		String getOpenIdUrl = open_url.replace("APPID", appid).replace("APPSECRET", appSecret).replace("CODE", String.valueOf(code));
		String result = httpsRequest(getOpenIdUrl, "POST");
		if(result != null && !"".equals(result)){
			Map<String,String> map = new Gson().fromJson(result, new TypeToken<Map<String,String>>(){}.getType());
			if(map.containsKey("errorCode") || map.get("errorCode") != null){
				return null;
			}else{
				String openId = map.get("openid");
				if(openId != null){
					return openId;
				}
				return null;
			}
		}else{
			return null;
		}
	}
}
